import { _decorator, Component, Node, game } from 'cc';
import { Debug } from '../../utils/Debug';
import { BaseObject } from './baseObject';
const { ccclass, property } = _decorator;

@ccclass('framingLoadingUtil')
export class framingLoadingUtil extends BaseObject {

    start() {
        game.addPersistRootNode(this.node);
    }

    static async framingLoad(childNodeCount: number, callback: (index: number) => void, duration: number = 3) {
        await this.executePreFrame(this.getItemGenerator(childNodeCount, callback), duration);
    }

    /**
     * 分帧执行 Generator 逻辑
     *
     * @param generator 生成器
     * @param duration 持续时间（ms），每次执行 Generator 的操作时，最长可持续执行时长。假设值为8ms，那么表示1帧（总共16ms）下，分出8ms时间给此逻辑执行
     */
    private static executePreFrame(generator: Generator, duration: number) {
        return new Promise((resolve, reject) => {
            let gen = generator;
            // 创建执行函数
            let execute = () => {
                // 执行之前，先记录开始时间
                let startTime = new Date().getTime();

                // 然后一直从 Generator 中获取已经拆分好的代码段出来执行
                for (let iter = gen.next(); ; iter = gen.next()) {
                    // 判断是否已经执行完所有 Generator 的小代码段，如果是的话，那么就表示任务完成
                    if (iter == null || iter.done) {
                        resolve(null);
                        return;
                    }

                    // 每执行完一段小代码段，都检查一下是否已经超过我们分配的本帧，这些小代码端的最大可执行时间
                    if (new Date().getTime() - startTime > duration) {
                        // 如果超过了，那么本帧就不在执行，开定时器，让下一帧再执行
                        setTimeout(() => {
                            execute();
                        }, 0);
                        return;
                    }
                }
            };

            // 运行执行函数
            execute();
        });
    }

    private static *getItemGenerator(length: number, callback: (index) => void) {
        for (let i = 0; i < length; i++) {
            yield callback(i);
        }
    }


    private static framingLoadQueue: Array<{ groupIndex: number, index: number, callback: (index: number) => void }> = [];
    private static generator: Generator;
    static async addFramingLoadQueue(childNodeCount: number, callback: (index: number) => void, duration: number = 1) {
        let startIndex = this.framingLoadQueue.length;
        for (let i = 0; i < childNodeCount; i++) {
            this.framingLoadQueue.push({
                groupIndex: startIndex + i,
                index: i,
                callback: callback
            });
        }
        if (this.generator == null) {
            this.generator = this.getQueueGenerator();
            await this.executePreFrame(this.generator, duration);
            Debug.log("粉针加载队列结束")
            this.generator = null;
        }
    }
    private static *getQueueGenerator() {
        while (framingLoadingUtil.framingLoadQueue.length > 0) {
            let item = framingLoadingUtil.framingLoadQueue.shift();
            yield item.callback(item.index);
        }
    }


    // update() {
    //     if (framingLoadingUtil.framingLoadQueue.length > 0) {
    //         let item = framingLoadingUtil.framingLoadQueue.shift();
    //         if (item != null) {
    //             item.callback(item.index);
    //         }
    //     }
    // }
}

